package com.youbenzi.dockerpool;

import java.util.Arrays;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class DockerPool {

	private DockerFactory dockerFactory;
	
	private Queue<ExecutorEnity> executors = new LinkedBlockingQueue<>();
	private static final ExecutorService executorService = Executors.newFixedThreadPool(2);
	
	public DockerPool(DockerFactory dockerFactory) {
		super();
		this.dockerFactory = dockerFactory;
	}

	public void init() {
		
		Config.init();
		System.out.println("运行模式：" + Config.mode);
		if(Config.mode.equals("client") || Config.mode.equals("all")) {
			work();
		}
		if(Config.mode.equals("server") || Config.mode.equals("all")) {
			initDocker();
		}
	}
	
	public void connect(String type, Executor executor) {
		executors.add(new ExecutorEnity(type, executor));
	}
	
	private void initDocker() {
		Map<String, String> server = Config.servers.get(Config.index);
		String host = server.get("host");
		System.out.println("需要创建的docker环境类型有：" + Arrays.toString(dockerFactory.types()));
		for (String dockerType : dockerFactory.types()) {
			int dockerConnectionNum = Register.num(dockerType, host);
			int needInitConnectionNum = Config.minDockerNum - dockerConnectionNum;
			System.out.println("环境：" + dockerType + " 目前已创建容器数为 " + dockerConnectionNum + "；需要创建数为 " + Config.minDockerNum);
			if(needInitConnectionNum > 0) {
				for(int i = 0; i< needInitConnectionNum; i++) {
					new DockerCreater(dockerType, host, dockerFactory).create();
				}
			}
		}
	}
	
	private void work() {
		new Thread(() -> {
			System.out.println("开启查找队列中的任务");
			while (true) {
				ExecutorEnity executorEnity = executors.peek();
				if(executorEnity != null) {
					try {
						DockerConnection connection = tryConnect(executorEnity.getType());
						executors.poll();
						executorService.execute(() ->{
							Executor executor = executorEnity.getExecutor();
							executor.execute(connection);
							if(executor.connectionAutoClose()) {
								connection.close();
							}
						});
					} catch (NotEnableConnectionException e) {
						System.out.println("暂无可用docker镜像");
					}
				}
				try {
					Thread.sleep(3L * 1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
	}
	
	private DockerConnection tryConnect(String type) {
		String host4Use = "";
		int connectionNum = 0;
		for (String host : Config.hosts) {
			int num = Register.num(type, host);
			if(num > connectionNum) {
				host4Use = host;
				connectionNum = num;
			}
		}
		
		return new DockerConnection(type, host4Use, dockerFactory);
	}
	
	protected class ExecutorEnity {
		private String type;
		private Executor executor;
		public ExecutorEnity(String type, Executor executor) {
			super();
			this.type = type;
			this.executor = executor;
		}
		public String getType() {
			return type;
		}
		public Executor getExecutor() {
			return executor;
		}
	}
}